from PyQt6.QtCore import QTimer
from typing import List, Callable, Optional
from cache.order_cache import order_cache
from utils.logger import logger
from datetime import datetime
import asyncio

class PriceMatcher:
    def __init__(self, price_list: List[float], push_callback: Callable[[dict, float, str], None], 
                 interval_ms: int = 1000, ws_manager=None):  # 添加ws_manager参数
        self.price_list = price_list
        self.push_callback = push_callback
        self.interval_ms = interval_ms
        self.index = 0
        self.timer = QTimer()
        self.timer.timeout.connect(self.match_next)
        self.running = False
        self.ws_manager = ws_manager  # 保存ws_manager引用
        
    async def notify_ticker_subscribers(self, price: float):
        """通知所有ticker订阅者当前价格"""
        if self.ws_manager:
            logger.info(f"[价格更新] 准备通知ticker订阅者，当前价格: {price}, 订阅者数量: {len(self.ws_manager.ticker_subscribers)}")
            try:
                await self.ws_manager.push_ticker_update(price)
                logger.info(f"[价格更新] 成功推送ticker更新，价格: {price}")
            except Exception as e:
                logger.error(f"[价格更新] 推送ticker更新失败: {str(e)}")
        else:
            logger.warning("[价格更新] WebSocketManager未初始化，无法推送ticker更新")
            
    def match_next(self):
        if self.index >= len(self.price_list):
            self.stop()
            return
            
        price = self.price_list[self.index]
        step = self.index + 1
        logger.info(f"[撮合轮询] 第{step}步，当前价格: {price}")
        
        # 创建事件循环用于异步推送ticker更新
        try:
            loop = asyncio.get_event_loop()
        except RuntimeError:
            loop = asyncio.new_event_loop()
            asyncio.set_event_loop(loop)
            
        # 使用asyncio.ensure_future来处理异步任务
        async def push_updates():
            try:
                if self.ws_manager and self.ws_manager.is_running:
                    await self.notify_ticker_subscribers(price)
                    logger.info(f"[撮合轮询] 第{step}步，已通知ticker订阅者，价格: {price}")
            except Exception as e:
                logger.error(f"推送Ticker更新失败: {str(e)}")
                
        # 创建并执行ticker更新任务
        future = asyncio.ensure_future(push_updates(), loop=loop)
        try:
            loop.run_until_complete(future)
        except Exception as e:
            logger.error(f"执行ticker更新任务失败: {str(e)}")

        # 处理订单撮合
        orders = order_cache.get_orders()
        now_str = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        
        # 开多订单撮合
        for order in orders['open']:
            if not order.get('matched') and price <= order['open_price']:
                match_msg = (
                    f"[撮合成交] 第{step}步 | {now_str} | 类型:开多 | 订单ID:{order['order_id']} | 成交价:{price} | 触发价:{order['open_price']}"
                )
                logger.info(match_msg)
                order_cache.mark_matched(order['order_id'], 'open')
                self.push_callback(order, order['open_price'], 'open')
                
        # 平多订单撮合
        for order in orders['close']:
            if not order.get('matched') and price >= order['close_price']:
                match_msg = (
                    f"[撮合成交] 第{step}步 | {now_str} | 类型:平多 | 订单ID:{order['order_id']} | 成交价:{price} | 触发价:{order['close_price']}"
                )
                logger.info(match_msg)
                order_cache.mark_matched(order['order_id'], 'close')
                self.push_callback(order, order['close_price'], 'close')
                
        self.index += 1

    def start(self):
        self.index = 0
        self.running = True
        self.timer.start(self.interval_ms)

    def stop(self):
        self.running = False
        self.timer.stop() 